package com.hisense.ovcloud.mqtt.business.service;

import cn.hutool.json.JSONUtil;
import com.hisense.ovcloud.commons.dto.req.GetPublicKeyReq;
import com.hisense.ovcloud.commons.dto.req.UpdateDeviceStatusReq;
import com.hisense.ovcloud.commons.dto.resp.GenerateAesKeyAndFetchPublicKeyResp;
import com.hisense.ovcloud.commons.dto.resp.GetPublicKeyResp;
import com.hisense.ovcloud.mqtt.business.config.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
@Slf4j
public class MqttClients {
    private final WebClient webClient;

    @Value("${business.mqttWarehouseUrl:ac-mqtt-warehouse:5814}")
    private String mqttWarehouseUrl;

    public MqttClients(@Qualifier("base") WebClient webClient) {
        this.webClient = webClient;
    }

    public Mono<String> getPublicKey(long majorDomainId, long subDomainId, String wifiId){
        return webClient.post()
                .uri(Constants.REST_SCHEMA_HTTP + mqttWarehouseUrl + "/zc-warehouse/v1/getPublicKey")
                .header(Constants.ZC.HEAHERS.HEADER_ZC_DOMAIN, String.valueOf(majorDomainId))
                .header(Constants.ZC.HEAHERS.HEADER_ZC_SUBDOMAIN, String.valueOf(subDomainId))
                .body(Mono.just(GetPublicKeyReq.builder().physicalDeviceId(wifiId).build()), GetPublicKeyReq.class)
                .retrieve()
                .bodyToMono(GetPublicKeyResp.class)
                .doOnSuccess(res -> {
                    log.info("succeed to call getPublicKey {} for wifiId {}", JSONUtil.toJsonStr(res), wifiId);
                })
                .doOnError(err -> log.error("failed to call getPublicKey for wifiId {}", wifiId, err))
                .zipWhen(result -> Mono.just(result.getPublicKey()), (x, y) -> y);
    }


    public Mono<Boolean> updateDeviceActivateStatus(long majorDomainId, String wifiId){
        return webClient.post()
                .uri(Constants.REST_SCHEMA_HTTP + mqttWarehouseUrl + "/zc-warehouse/v1/updateDeviceStatus")
                .header(Constants.ZC.HEAHERS.HEADER_ZC_DOMAIN, String.valueOf(majorDomainId))
                .body(Mono.just(UpdateDeviceStatusReq.builder().deviceId(wifiId).build()), UpdateDeviceStatusReq.class)
                .retrieve()
                .bodyToMono(Boolean.class)
                .doOnSuccess(res -> {
                    log.info("succeed to call updateDeviceStatus for wifiId {}", wifiId);
                })
                .doOnError(err -> log.error("failed to call updateDeviceStatus for wifiId {}", wifiId, err));
    }

    public Mono<GenerateAesKeyAndFetchPublicKeyResp> generateAesKeyAndFetchPublicKey(String majorDomainId, String subDomainId, String wifiId){
        return webClient.post()
                .uri(Constants.REST_SCHEMA_HTTP + mqttWarehouseUrl + "/zc-warehouse/v1/generateAesKeyAndFetchPublicKey")
                .header(Constants.ZC.HEAHERS.HEADER_ZC_DOMAIN, majorDomainId)
                .header(Constants.ZC.HEAHERS.HEADER_ZC_SUBDOMAIN, subDomainId)
                .body(Mono.just(GetPublicKeyReq.builder().physicalDeviceId(wifiId).build()), GetPublicKeyReq.class)
                .retrieve()
                .bodyToMono(GenerateAesKeyAndFetchPublicKeyResp.class)
                .doOnSuccess(res -> {
                    log.info("succeed to call generateAesKeyAndFetchPublicKey {} for wifiId {}", JSONUtil.toJsonStr(res), wifiId);
                })
                .doOnError(err -> log.error("failed to call generateAesKeyAndFetchPublicKey for wifiId {}", wifiId, err));
    }
}
